package com.invengo.library_rfid.analyze.utils.uhf;



import com.invengo.library_rfid.analyze.utils.uhf.TIAOMHZH.CBookIDRule;
import com.invengo.library_rfid.analyze.utils.uhf.entity.TagInfoInDto;
import com.invengo.library_rfid.analyze.utils.uhf.entity.TagInfoInput;
import com.invengo.library_rfid.analyze.utils.uhf.formatHelp.CBookEpcCodeEx;
import com.invengo.library_rfid.analyze.utils.uhf.formatHelp.CTagMemoryInfo;
import com.invengo.library_rfid.analyze.utils.uhf.utils.ChangeDataType;

import java.util.Arrays;
import java.util.Random;

public class UHFApi {
    /// <summary>
    /// 解码
    /// </summary>
    /// <param name="tagInfoInput">需要解析的数据对象</param>
    /// <returns></returns>
    public static TagInfoInDto DeserialiseTagInfo(String tid, String epc) throws Exception {
        return Deserialise(tid, epc);
    }

    /// <summary>
    /// 解码
    /// </summary>
    /// <param name="tagInfoInput">需要解码对象，EPC不能为空</param>
    /// <returns></returns>
    public static String DeserialiseUserData(String tid, String epc) throws Exception {
        return DeserialiseTagInfo(tid, epc).Barcode;
    }

    /// <summary>
    /// 编码
    /// </summary>
    /// <param name="tagInfoInput">编码对象，Barcode不能为空</param>
    /// <returns></returns>
    public String SerialiseUserData(TagInfoInput tagInfoInput) throws Exception {
        if (tagInfoInput.VersionNo >= 1 && tagInfoInput.VersionNo <= 10) {
            if (CBookIDRule.BookIDToEPC(tagInfoInput.Barcode, tagInfoInput.LibraryCode) == 0) {
                return "";
            }
        }
        return Serialise(tagInfoInput);
    }


    private String Serialise(TagInfoInput tagInfoInput) throws Exception {
        String epc = "";
        CBookEpcCodeEx objEpcCodeEx = new CBookEpcCodeEx();
        CTagMemoryInfo cTagMemoryInfo = new CTagMemoryInfo();
        objEpcCodeEx.m_lBussinessID = cTagMemoryInfo._nBussinessCode;
        objEpcCodeEx.m_lBussinessID = 194;//0xC2
        objEpcCodeEx.m_lLibCode = tagInfoInput.LibraryCode;
        objEpcCodeEx.m_lSortPort = 0;//默认0
        objEpcCodeEx.m_lLocation = 0;//馆藏地ID号
        objEpcCodeEx.m_lTagType = 0;
        objEpcCodeEx.m_lStatus = 1;//流通标识
        objEpcCodeEx.m_lEAS = tagInfoInput.Eas == true ? 1 : 0;//1:报警;0:不报警
        objEpcCodeEx.m_lVersion = tagInfoInput.VersionNo;
        //objEpcCodeEx.m_contentIndex.SetContentIndex(objTagFormatInfo.OID_High_School_Index);//高校模型用户数据区内容
        objEpcCodeEx.m_lRemain = 0;
        objEpcCodeEx.m_szID = tagInfoInput.Barcode;
        objEpcCodeEx.m_lIDLength = tagInfoInput.Barcode.length();
        objEpcCodeEx.m_lID = CBookIDRule.BookIDToEPC(tagInfoInput.Barcode, tagInfoInput.LibraryCode);
        switch (tagInfoInput.VersionNo) {
            case 1://远望谷1代格式
                objEpcCodeEx.m_nEPCLength = 12;
                epc = SerialiseVersion(objEpcCodeEx);
                break;
            case 2://远望谷2代格式
                objEpcCodeEx.m_nEPCLength = 30;
                epc = SerialiseVersion(objEpcCodeEx);
                break;
            case 3://远望谷档案馆格式
                break;
            case 4://远望谷4代格式
                objEpcCodeEx.m_nEPCLength = 12;
                epc = SerialiseVersionEncrypt(objEpcCodeEx);
                break;
            case 5://虚拟版本，会随机从6~8之间选取一种格式
            case 6://会随机从6~8之间选取一种格式
            case 7://会随机从6~8之间选取一种格式
            case 8://会随机从6~8之间选取一种格式
                objEpcCodeEx.m_nEPCLength = 12;
                int a = 6;  // 区间的下限
                int b = 8; // 区间的上限
                Random rand = new Random();
                objEpcCodeEx.m_lVersion = a + new Random().nextInt(b - a + 1);
                epc = SerialiseVersionEncrypt(objEpcCodeEx);
                break;
            case 11:
                break;
            case 12:
                break;
            case 1011:
            case 1021:
            case 1031:
            case 1041:
            case 1051:
                objEpcCodeEx.m_nEPCLength = 12;
                epc = SerialiseVersion(objEpcCodeEx);
                break;
            case 1012:
            case 1042:
                objEpcCodeEx.m_nEPCLength = 16;
                epc = SerialiseVersion(objEpcCodeEx);
                break;
            case 1010:
            case 1040:
                break;
        }
        return epc;
    }

    private String SerialiseVersion(CBookEpcCodeEx objEpcCodeEx) throws Exception {
        String epcStr = "";
        byte[] epcData = new byte[objEpcCodeEx.m_nEPCLength];
        objEpcCodeEx.GetBytes(epcData);//传入的标签数据
        for (int i = 0; i < epcData.length; i++) {
//            epcStr += epcData[i].ToString("X2");
            epcStr += String.format("%02X", epcData[i]);
        }
        return epcStr;
    }

    private String SerialiseVersionEncrypt(CBookEpcCodeEx objEpcCodeEx) throws Exception {
        String s = "0123456789";
        String ss = "9874563210";
        String sEPCOrder = Long.toString(objEpcCodeEx.m_lID);
        String m_lID = "";
        switch ((int) objEpcCodeEx.m_lVersion) {
            case 4:
                s = "0123456789";
                ss = "9874563210";
                break;
            case 6:
                s = "0123456789";
                ss = "8745632109";
                break;
            case 7:
                s = "0123456789";
                ss = "7456321098";
                break;
            case 8:
                s = "0123456789";
                ss = "4563210987";
                break;
        }
        sEPCOrder = Long.toString(objEpcCodeEx.m_lID);
        m_lID = "";
        if (sEPCOrder.length() > 4)//
        {
            int len = sEPCOrder.length();
            sEPCOrder = sEPCOrder.substring(sEPCOrder.length() - 4, 4);

            for (char c : sEPCOrder.toCharArray()) {
                m_lID += ss.charAt(s.indexOf(c));
            }
            m_lID = Long.toString(objEpcCodeEx.m_lID).substring(0, len - 4) + m_lID;
        } else {
            m_lID = sEPCOrder;
        }
        objEpcCodeEx.m_lID = Long.parseLong(m_lID);// Convert.ToInt64(m_lID);//bookinfo.nEPCOrder;
        return SerialiseVersion(objEpcCodeEx);
    }

//    解码方法

    private static TagInfoInDto Deserialise(String tid, String epc) throws Exception {
        TagInfoInDto tagInfoInDto = new TagInfoInDto();
        tagInfoInDto.Epc = epc;
        tagInfoInDto.Tid = tid;
        tagInfoInDto.Success = false;
        byte[]  byData = ChangeDataType.convertHexToBytes(epc);
        CBookEpcCodeEx cBookEpcCodeEx = new CBookEpcCodeEx(byData);
        if (cBookEpcCodeEx.m_lTagType == 0) {
            long lEPCOrder = cBookEpcCodeEx.m_lID;
            if (Arrays.asList(new long[]{4, 6, 7, 8}).contains(cBookEpcCodeEx.m_lVersion)) {
                String s = "0123456789";
                String ss = "9874563210";
                String sEPCOrder = "";
                String m_lID = Long.toString(lEPCOrder);
                switch ((int) cBookEpcCodeEx.m_lVersion) {
                    case 4:
                        s = "0123456789";
                        ss = "9874563210";
                        break;
                    case 6:
                        s = "0123456789";
                        ss = "8745632109";
                        break;
                    case 7:
                        s = "0123456789";
                        ss = "7456321098";
                        break;
                    case 8:
                        s = "0123456789";
                        ss = "4563210987";
                        break;
                }
                sEPCOrder = Long.toString(lEPCOrder);
                m_lID = "";
                if (sEPCOrder.length() > 4)//
                {
                    int len = sEPCOrder.length();
                    sEPCOrder = sEPCOrder.substring(sEPCOrder.length() - 4, 4);
                    for (char c : sEPCOrder.toCharArray()) {
                        m_lID += s.charAt(ss.indexOf(c));
                    }
                    m_lID = Long.toString(lEPCOrder).substring(0, len - 4) + m_lID;
                } else {
                    m_lID = sEPCOrder;
                }
                lEPCOrder = Long.parseLong(m_lID);
                tagInfoInDto.Barcode = CBookIDRule.EPCToBookID(lEPCOrder, (int) cBookEpcCodeEx.m_lLibCode);
            } else if (cBookEpcCodeEx.m_lVersion == 1) {
                tagInfoInDto.Barcode = CBookIDRule.EPCToBookID(lEPCOrder, (int) cBookEpcCodeEx.m_lLibCode);
            } else {
                tagInfoInDto.Barcode = cBookEpcCodeEx.m_szID;
            }
        }
        if (tagInfoInDto.Barcode == null | tagInfoInDto.Barcode.equals("")) {
            tagInfoInDto.VersionNo = (int) cBookEpcCodeEx.m_lVersion;
            tagInfoInDto.Eas = cBookEpcCodeEx.m_lEAS == 1 ? true : false;
            tagInfoInDto.LibraryCode = Long.toString(cBookEpcCodeEx.m_lLibCode);
            tagInfoInDto.Success = true;
        }
        return tagInfoInDto;
    }
}
